import {
    Button,
    Input,
    Message,
    Select,
    Table,
    Tag,
} from '@arco-design/web-react'
import { IconCopy } from '@arco-design/web-react/icon'
import classNames from 'classnames'
import React from 'react'
import {
    IApiItem,
    IVariableItem,
    IVariableType,
} from '../../../../utils/interfaces'
import { syncArrays } from '../../../../utils/syncArrays'
import VariableValue from './VariableValue'

interface IVariablesProps {
    // updateKey，当这个值发生变化时更新内部状态
    updateKey?: string
    // 是默认期望吗
    isDefault?: boolean
    // 默认期望中的变量值
    defaultExpectVariables?: IApiItem['variables']
    // 值
    value: IApiItem['variables']
    // 改变
    onChange: (value: IApiItem['variables']) => void
}

const varTypeOptions: {
    label: IVariableType
    value: IVariableType
    defaultValue: IVariableValueType
}[] = [
    {
        label: 'string',
        value: 'string',
        defaultValue: '',
    },
    {
        label: 'number',
        value: 'number',
        defaultValue: 0,
    },
    {
        label: 'boolean',
        value: 'boolean',
        defaultValue: false,
    },
    { label: 'null', value: 'null', defaultValue: null },
]

const Variables: React.FC<IVariablesProps> = ({
    updateKey,
    isDefault,
    defaultExpectVariables,
    value,
    onChange: propsOnChange,
}) => {
    // 变化
    const handleChange = <K extends keyof IVariableItem>(
        index: number,
        key: K,
        newValue: IVariableItem[K],
    ) => {
        const oldValue = value || []
        const cloned = [...oldValue]
        cloned[index] = {
            ...cloned[index],
            [key]: newValue,
        }
        propsOnChange(cloned)
    }

    // 批量变化
    const handleBatchChange = <K extends keyof IVariableItem>(
        index: number,
        newValues: Partial<IVariableItem>,
    ) => {
        const oldValue = value || []
        const cloned = [...oldValue]
        cloned[index] = {
            ...cloned[index],
            ...newValues,
        }
        propsOnChange(cloned)
    }

    // 删除
    const handleDelete = (index: number) => {
        const oldValue = value || []
        const cloned = [...oldValue]
        cloned.splice(index, 1)
        propsOnChange(cloned)
    }

    // 根据默认期望更新当前期望
    const syncFromDefault = () => {
        // 默认期望不需要同步，默认期望不存在时不需要同步
        if (isDefault || !defaultExpectVariables?.length) {
            return
        }
        propsOnChange(
            syncArrays(defaultExpectVariables, value || [], {
                uniqueKey: 'id',
                syncProps: ['name'],
            }),
        )
    }

    useEffect(() => {
        syncFromDefault()
    }, [updateKey])

    return (
        <div className='my-2'>
            <Table
                pagination={false}
                hover={false}
                noDataElement='暂无数据'
                rowKey='id'
                columns={[
                    {
                        title: '变量名',
                        dataIndex: 'name',
                        render: (col, _item, index) => {
                            return (
                                <div className='flex items-center'>
                                    <Input
                                        disabled={!isDefault}
                                        value={col}
                                        onChange={(v) =>
                                            handleChange(index, 'name', v)
                                        }
                                    />
                                    <Button
                                        className='ml-1'
                                        icon={<IconCopy />}
                                        onClick={() => {
                                            navigator.clipboard.writeText(
                                                `!{{ ${col} }}`,
                                            )
                                            Message.success('复制成功')
                                        }}
                                    />
                                </div>
                            )
                        },
                    },
                    {
                        title: '类型',
                        dataIndex: 'type',
                        width: 180,
                        render: (col, _item, index) => {
                            return (
                                <Select
                                    value={col || 'string'}
                                    options={varTypeOptions}
                                    onChange={(v) => {
                                        const optionItem = varTypeOptions.find(
                                            (item) => item.value === v,
                                        )
                                        handleBatchChange(index, {
                                            type: v,
                                            value: optionItem?.defaultValue,
                                        })
                                    }}
                                />
                            )
                        },
                    },
                    {
                        title: 'Mock规则',
                        dataIndex: 'mockRule',
                        render: (col, item, index) => {
                            return (
                                <div className='flex w-full gap-1 items-center'>
                                    <Input
                                        value={col}
                                        onChange={(v) =>
                                            handleChange(index, 'mockRule', v)
                                        }
                                    />
                                    <Tag
                                        className={classNames(
                                            `shrink-0
                                    flex items-center justify-center 
                                    rounded-md cursor-pointer text-gray-500`,
                                        )}
                                        size='large'
                                        color='blue'
                                        checkable
                                        checked={item?.useMock}
                                        onCheck={(checked) => {
                                            if (checked && !item?.mockRule) {
                                                Message.warning(
                                                    '使用mock无效：未填写mock规则',
                                                )
                                            }
                                            handleChange(
                                                index,
                                                'useMock',
                                                checked,
                                            )
                                        }}
                                    >
                                        M
                                    </Tag>
                                </div>
                            )
                        },
                    },
                    {
                        title: '值',
                        dataIndex: 'value',
                        render: (col, item, index) => {
                            return (
                                <VariableValue
                                    variableItem={item}
                                    value={col}
                                    onChange={(v) =>
                                        handleChange(index, 'value', v)
                                    }
                                />
                            )
                        },
                    },
                    {
                        title: '操作',
                        render: (_col, _item, index) => {
                            return (
                                <Button
                                    disabled={!isDefault}
                                    size='small'
                                    status='danger'
                                    onClick={() => handleDelete(index)}
                                >
                                    删除
                                </Button>
                            )
                        },
                    },
                ]}
                data={value}
            />
        </div>
    )
}

export default Variables
